package com.weiyuwqj.server.service.invest.module;

import com.weiyuwqj.api.constant.OperateContants;
import com.weiyuwqj.api.util.*;
import com.weiyuwqj.server.service.account.module.DealAction;
import com.weiyuwqj.server.service.account.module.DealModule;
import com.weiyuwqj.server.service.account.module.action.user.invest.InvestDealAction;
import com.weiyuwqj.server.mapper.*;
import com.weiyuwqj.api.common.Calculator;
import com.weiyuwqj.api.constant.ItemStatus;
import com.weiyuwqj.api.exception.CrowdException;
import com.weiyuwqj.api.model.*;
import com.weiyuwqj.server.service.finance.module.OperateModule;
import com.weiyuwqj.server.service.finance.module.action.ExpendOperateAction;
import com.weiyuwqj.server.service.finance.module.action.OperateAction;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Copyright 2015-2019 Yunfucloud technology co., Ltd.
 * Created by fuxx on 16/2/29.
 */
@Component
public class InvestModule {

    @Autowired
    private BusAccountMapper accountMapper;
    @Autowired
    private BasItemMapper itemMapper;
    @Autowired
    private BasCouponMapper basCouponMapper;
    @Autowired
    private BusItemInvestMapper investMapper;
    @Autowired
    private BusVerifyLogMapper verifyLogMapper;
    @Autowired
    private DealModule dealModule;
    @Autowired
    private BusUserStatMapper userStatMapper;
    @Autowired
    private BasTicketMapper ticketMapper;
    @Autowired
    private BusUserIntegralMapper userIntegralMapper;
    @Autowired
    private OperateModule operateModule;

    /**
     * 投标
     *
     * @param userId     用户ID
     * @param amount     投资金额
     * @param item       标
     * @param available  允许投标金额
     * @param couponId
     * @param ticketId   加息券ID
     * @param investType 投资类型
     * @param freeOrder  冻结订单号
     */

    public Map doInvest(Integer userId,Double amount,BasItem item,BigDecimal available,Integer couponId,Integer investType,
                        Integer ticketId,String freeOrder){
        if(userId<1){
            throw new CrowdException("item.invest.session_out");
        }

        int itemId = item.getId();
        BusAccount account = accountMapper.getBusAccountByUserId(userId);

        //投资只能投资整数
        BigDecimal amountDecimal = BigDecimal.valueOf(amount);
        amountDecimal = amountDecimal.setScale(0, BigDecimal.ROUND_DOWN);
        MyAssertUtils.isTrue(amountDecimal.compareTo(item.getItemSingleMinInvestment())>=0,"debt.company.amount_limit");
        MyAssertUtils.isTrue(amountDecimal.compareTo(BigDecimal.ZERO)>0,"debt.invest_mount_must_more_than_zero");
        BigDecimal itemBalance = available.subtract(item.getItemOngoingAccount());

        //判断投资金额是否小于项目余额
        if (amountDecimal.compareTo(itemBalance) == 1) {
            throw new CrowdException("item.invest.item_no_more_balance");
        }

        Double d = itemBalance.doubleValue();
        if (d.equals(0.0)) {
            throw new CrowdException("item.invest.item_no_more_balance");
        }
        BasCoupon coupon = null;
        if (null != couponId && couponId > 0) {
            //向红包表插入investId
            coupon = basCouponMapper.selectByPrimaryKey(couponId);
        }

        if(item.getItemSingleMinInvestment().compareTo(BigDecimal.ZERO)>0 &&
                item.getItemSingleMinInvestment().compareTo(item.getItemAccount().subtract(item.getItemOngoingAccount()))<0){
            if(item.getItemSingleMinInvestment().compareTo(amountDecimal)>0){
                throw new CrowdException("item.invest.less_min_investment");
            }
        }

        //检查账号余额是否大于本次投标金额
        if(account.getCash().compareTo(amountDecimal.subtract(coupon==null?BigDecimal.ZERO:coupon.getAmount()))<0){
            throw new CrowdException("item.invest.account_no_more_balance");
        }

        //检查最大投资情况
        if (item.getItemMaxInvestment() != null
                && item.getItemMaxInvestment().compareTo(BigDecimal.ZERO) > 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", userId);
            map.put("itemId", itemId);
            Map<String, Object> totalInvestMap = investMapper.totalInvest(map);
            BigDecimal totalInvest = MapUtils.getDecimal(totalInvestMap, "invest_deal_total");
            totalInvest = totalInvest.add(amountDecimal);
            if (totalInvest.compareTo(item.getItemMaxInvestment()) > 0) {
                throw new CrowdException("item.great_max_investment");
            }
        }

        BusItemInvest invest = new BusItemInvest();
        String investOrder = RandomCodesUtils.getOrderNo();

        Map statMap = new HashMap();
        statMap.put("userId", userId);
        BusUserStat stat = userStatMapper.getOneByUserId(statMap);
        if (stat.getInvestCount() != 0) {
            invest.setInvestOrder(investOrder);
        } else {
            invest.setInvestOrder(investOrder + "s");
        }

        invest.setUserId(userId);
        invest.setItemId(itemId);
        invest.setInvestCurrent(0);
        invest.setInvestType(investType);
        invest.setInvestAmount(BigDecimal.valueOf(amount));
        invest.setInvestStatus(0);
        invest.setAddip(IpUtils.get());
        invest.setAddtime(new Date());

        System.out.println("______1__amountDecimal:"+amountDecimal+"________1_____itemBalance:"+itemBalance);
        BigDecimal dealAmount=BigDecimal.ZERO;
        BigDecimal scale;
        if(available.compareTo(item.getItemAccount())<0
                &&amountDecimal.compareTo(itemBalance)>=0){
                dealAmount = itemBalance;
                scale=available.divide(item.getItemAccount(), 2, BigDecimal.ROUND_DOWN)
                        .multiply(BigDecimal.valueOf(100))
                        . setScale(2);
        }else if(amountDecimal.compareTo(itemBalance)>=0){
            dealAmount=itemBalance;
            scale=BigDecimal.valueOf(100);
            System.out.println("________amountDecimal:"+amountDecimal+"_____________itemBalance:"+itemBalance);
            if(item.getItemStatus()==ItemStatus.OPEN){
                itemMapper.updateItemStatus(ItemStatus.OPEN, ItemStatus.FULL_COMPLETE,itemId);
            }else if(item.getItemStatus()==ItemStatus.FIRST){
                itemMapper.updateItemStatus(ItemStatus.FIRST, ItemStatus.FULL_COMPLETE,itemId);
            }else {
                throw new CrowdException("invest.item_full.status_error");

            }
            //插入日志类型3
            BusVerifyLog log = new BusVerifyLog();
            log.setOperateUserId(1);
            log.setContent("项目满标：" + item.getItemName());
            log.setAddtime(new Date());
            log.setType((byte) 3);
            log.setItemId(itemId);
            log.setStatus((byte) 1);
            log.setAddip(IpUtils.get());
            verifyLogMapper.insert(log);

        } else {
            dealAmount = amountDecimal;
            scale = item.getItemOngoingAccount().add(amountDecimal).multiply(BigDecimal.valueOf(100))
                    .divide(item.getItemAccount(), 2, BigDecimal.ROUND_DOWN)
                    .setScale(2);
        }


        int count = itemMapper.updateItemScale(dealAmount, item.getItemOngoingAccount(), scale, itemId);
        if (count < 1) {
            throw new CrowdException("item.invest.busy");
        }

        invest.setInvestDealAmount(dealAmount);
        //计算本次投资预计收益
        //判断项目是否是浮动利率项目
        int x = 0;

        BigDecimal interest = Calculator.getInterest(invest.getInvestDealAmount(), item);

        //加息券利率计算收益
        BasTicket ticket;
        BigDecimal totalTicketInterest = BigDecimal.ZERO;
        if (null != ticketId && ticketId > 0) {
            BasItem from = new BasItem();
            BeanUtils.copyProperties(item, from);
            //查询加息券信息
            ticket = ticketMapper.selectByPrimaryKey(ticketId);
            //计算未加息收益
            if (item.getItemCycle() - ticket.getUsefulLife() >= 0) {
                from.setItemCycle(item.getItemCycle() - ticket.getUsefulLife());
            } else {
                from.setItemCycle(0);
            }
            BigDecimal addTicketInterest = Calculator.addRateInterest(invest.getInvestDealAmount(), from);
            //计算加息收益
            if (ticket.getUsefulLife() - item.getItemCycle() >= 0) {
                from.setItemCycle(item.getItemCycle());
            } else {
                from.setItemCycle(ticket.getUsefulLife());
            }
            from.setItemRate(item.getItemRate().add(ticket.getRate()));
            BigDecimal ticketInterest = Calculator.addRateInterest(invest.getInvestDealAmount(), from);
            //计算总收益
            totalTicketInterest = addTicketInterest.add(ticketInterest);
            invest.setCollectInterest(totalTicketInterest);
            invest.setAdditionalRateAmount(totalTicketInterest.subtract(interest));
        } else {
            invest.setCollectInterest(interest);
            invest.setAdditionalRateAmount(totalTicketInterest);
        }

        invest.setCollectPrincipal(invest.getInvestDealAmount());
        invest.setCollectAmount(invest.getCollectPrincipal().add(invest.getCollectInterest()));
        invest.setActualCollectAmount(BigDecimal.ZERO);
        invest.setActualCollectInterest(BigDecimal.ZERO);
        invest.setActualCollectPrincipal(BigDecimal.ZERO);
        invest.setActualUncollectAmount(BigDecimal.ZERO);
        invest.setActualUncollectInterest(BigDecimal.ZERO);
        invest.setActualUncollectPrincipal(BigDecimal.ZERO);
        invest.setDebtTransferStatus(0);
        invest.setFreezeOrderNo(freeOrder);
        investMapper.insertInvest(invest);

        if (null != couponId && couponId > 0 && coupon != null) {
            if (dealAmount.compareTo(coupon.getRequireAmount()) == -1) {
                throw new CrowdException("item.invest.amount_no_meet_coupon_amount");
            }
            Map couponMap = new HashMap();
            couponMap.put("investId", invest.getId());
            couponMap.put("debtInvestId", 0);
            couponMap.put("useTime", new Date());
            couponMap.put("userId", userId);
            couponMap.put("id", couponId);
            couponMap.put("newStatus", 1);
            couponMap.put("oldStatus", 2);
            count = basCouponMapper.updateCouponStatus(couponMap);
            if (count < 1) {
                throw new CrowdException("invest.coupon_status_update_error");
            }
            DealAction action = new InvestDealAction();
            action.deal(invest.getUserId(), dealAmount.subtract(coupon.getAmount()), item.getItemName() + "投资,红包" + coupon.getAmount() + "元");
            dealModule.dealAction(action);
            OperateAction operate = new ExpendOperateAction();
            operate.operateAction(investOrder, OperateContants.INVESTORS_INVEST,itemId,
                    item.getItemName(),dealAmount.subtract(coupon.getAmount()));
            operateModule.operateAction(operate);
        } else {
            DealAction action = new InvestDealAction();
            action.deal(invest.getUserId(), dealAmount, item.getItemName() + "投资冻结");
            dealModule.dealAction(action);
            OperateAction operate = new ExpendOperateAction();
            operate.operateAction(investOrder, OperateContants.INVESTORS_INVEST,itemId,
                    item.getItemName(),dealAmount);
            operateModule.operateAction(operate);
        }

        //如果使用了加息券
        if (ticketId != null && ticketId > 0) {
            BasTicket basTicket = ticketMapper.selectByPrimaryKey(ticketId);
            if (dealAmount.compareTo(basTicket.getRequireAmount()) == -1) {
                throw new CrowdException("item.invest.amount_no_meet_ticket_amount");
            }
            //向红包表插入investId
            Map ticketMap = new HashMap();
            ticketMap.put("investId", invest.getId());
            ticketMap.put("useTime", new Date());
            ticketMap.put("userId", userId);
            ticketMap.put("id", ticketId);
            count = ticketMapper.updateTicketStatus(ticketMap);
            if (count < 1) {
                throw new CrowdException("invest.coupon_status_update_error");
            }
        }
        //投资加积分
        BigDecimal integer = dealAmount.divide(BigDecimal.valueOf(100), 0, BigDecimal.ROUND_HALF_EVEN);
        userIntegralMapper.modifyAmount(integer, integer, userId);

        Map investMap = new HashMap();
        investMap.put("userId", userId);
        investMap.put("investAmount", dealAmount);
        userStatMapper.updateInvest(investMap);
        Map param = new HashMap();
        param.put("investOrder", investOrder);
        param.put("dealAmount", dealAmount);
        param.put("freezeOrderNo", invest.getFreezeOrderNo());
        return param;
    }


    /**
     * 默认PC端投资
     *
     * @param userId     用户ID
     * @param amount     投资金额
     * @param item       项目ID
     * @param couponId   红包ID
     * @param investType 投资类型
     * @param ticketId   加息卷
     * @param freeOrder  冻结订单号
     * @return 投资结果
     */

    public Map doInvest(Integer userId,Double amount,BasItem item,Integer couponId,Integer investType,Integer ticketId,String freeOrder){
       return doInvest(userId, amount, item, item.getItemAccount(), couponId, investType, ticketId,freeOrder);

    }


}

